import { _decorator, Node, Vec3 } from 'cc';
import { BallGameBase } from './BallGameBase';
import { BallAttribute, BallColor } from '../core/BallAttribute';
import { Game, HitBallAttribute } from '../core/Game';
import { PlayUser } from '../core/PlayUser';
import { EventManager } from '../core/EventManager';
export class EightBallGame extends BallGameBase {
  constructor(node: Node) {
    super(node);
  }
  public initBallsPosition() {
    const snookerNode = this.billiamNode.getChildByName('SnookerBalls');
    snookerNode.active = false;
    // 初始化球的位置
    const points = BallAttribute.getBallRandomIndexs();
    this.resetBallOrderPosition(points);
    // 设置白球的位置
    EventManager.Instance().Emit('InitMainBallPosition', new Vec3(10, 0, 0));
  }
  // 游戏是否已经结束
  public checkGameEnd() {
    const balls = this.getActiveBalls();
    for (const b of balls) {
      const ba = BallAttribute.getBallByName(b.name);
      if (ba.isBlackBall8()) {
        return false;
      }
    }
    return true;
  }
  // 是否进球得分
  public hasHoledScore(hitBallList: Array<HitBallAttribute>, step: number, color: BallColor) {
    const balls = hitBallList;
    for (var i=balls.length-1; i>=0; i--) {
      if (balls[i].step !== step) {
        return false;
      }
      if (balls[i].ba.isMainWhiteBall()) continue;
      if (color.isSureColored()) {
        if (balls[i].ba.color === color.color) {
          return true;
        }
      } else {
        return true;
      }
    }
    return false;
  }
  public isTargetHitBall(color: BallColor, name: string) {
    const ba = BallAttribute.getBallByName(name);
    if (!color.isSureColored()) {
      return !ba.isBlackBall8();
    }
    return color.isSameColor(ba.color);
  }
  public isIllegalHitBall(firstCollideBall: BallAttribute, hitBallList: Array<HitBallAttribute>, step: number, color: BallColor) {
    const res = super.illeageHitBallResult(firstCollideBall, hitBallList, step, color);
    return res;
  }
  // 球桌上当前活跃的球
  public getActiveBalls() {
    const bList = [];
    const balls = this.billiamNode.getChildByName('Balls').children;
    for (const b of balls) {
      if (b.active) {
        bList.push(b);
      }
    }
    return bList;
  }
  // 当前击球 和受保护 的球列表
  public getHitProtectBalls(color: BallColor) {
    const hitBalls = [];
    const protectBalls = [];
    const balls = this.getActiveBalls();
    var blackBall = null;
    for (const b of balls) {
      const ba = BallAttribute.getBallByName(b.name);
      if (ba.isBlackBall8()) {
        blackBall = b;
      } else if (color.isUnknowColor()) {
        hitBalls.push(b);
      } else if (color.isSameColor(ba.color)) {
        hitBalls.push(b);
      } else {
        protectBalls.push(b);
      }
    }
    if (!blackBall) {
      return { hitBalls, protectBalls };
    }
    if (hitBalls.length > 0) {
      protectBalls.push(blackBall);
    } else {
      hitBalls.push(blackBall);
    }
    return { hitBalls, protectBalls };
  }

  public getCurrentStepScore(hitBallList: Array<HitBallAttribute>, step: number, color: BallColor) {
    return 0;
  }

  public getUserHitColorText(color: BallColor) {
    return color.getColorText();
  }

  public swapCurrentUserColor(hasExchangeUser: boolean) {
    if (Game.Instance().hasSureColor) {
      this.changeUserHitBallColor(0);
      this.changeUserHitBallColor(1);
      return;
    }
    var hasSingleColor = false;
    var hasTwoColor = false;
    const balls = Game.Instance().hitBallList;
    for (var i=balls.length-1; i>=0; i--) {
      if (balls[i].step === Game.Instance().currentStep) {
        if (balls[i].ba.isSingleColorBall()) {
          hasSingleColor = true;
        } else if (balls[i].ba.isTwoColorBall()) {
          hasTwoColor = true;
        }
      } else {
        break;
      }
    }
    // 都有进球，则还是未确定
    if (hasSingleColor && hasTwoColor) {
      return;
    }
    if (hasTwoColor) {
      Game.Instance().setCurrentUserColor(BallAttribute.TwoColorBall);
    }
    if (hasSingleColor) {
      Game.Instance().setCurrentUserColor(BallAttribute.SingleColorBall);
    }
  }
  public isCurrentUserWin(side: number, isIlleagel: boolean) {
    // 已经交换击球了，上一个用户违规，当前用户胜利
    if (isIlleagel) return true;
    // 通过判断黑8球是谁打进的
    const hitBallList = Game.Instance().hitBallList;
    var userId = '';
    var userSide = side;
    for (var i=hitBallList.length-1; i>=0; i--) {
      if (hitBallList[i].ba.isBlackBall8()) {
        userId = hitBallList[i].userId;
        break;
      }
    }
    if (userId !== Game.Instance().playUsers[side].userAttribute.userId) {
      userSide = 1 - side;
    }
    const color = Game.Instance().playUsers[userSide].color;
    if (color.isBlackBallEight()) {
      return (userSide === side);
    }
    return (userSide !== side);
  }
  public penalyScore() {
    return 0;
  }
  public isExcellentLevel(hitBallList: Array<HitBallAttribute>, step: number, color: BallColor, userId: string) : number {
    // 一杆进两个球以上 鼓掌 1
    // 连续进3个球，优秀 2
    const steps = [0, 0, 0];
    for (var i = hitBallList.length -1; i>=0; i--) {
      const hba = hitBallList[i];
      if (hba.userId === userId) {
        if (color.color === hba.ba.color) {
          if (hba.step === step) {
            steps[0] += 1;
          } else if (hba.step === step-1) {
            steps[1] += 1;
          } else if (hba.step === step-2) {
            steps[2] += 1;
          } else {
            break;
          }
        }
      } else { break; }
    }
    if (steps[0] >= 2) return 1;
    if (steps[0] >= 1 && steps[1] >= 1 && steps[2] >= 1) return 2;
    
    return 0;
  }
  // 所有球的信息
  public getAllBallList() {
    const mainBall = this.billiamNode.getChildByName('MainBall').getChildByName('WhiteBall').getChildByName('BallSphereMain');
    const balls = this.billiamNode.getChildByName('Balls').children;
    return this.getNetFrameBallList(mainBall, balls);
  }

  // 所有球节点信息
  public getAllBallNodeList() {
    const bList: Array<Node> = [];
    const mainBall = this.billiamNode.getChildByName('MainBall').getChildByName('WhiteBall').getChildByName('BallSphereMain');
    bList.push(mainBall);
    const balls = this.billiamNode.getChildByName('Balls').children;
    bList.push(...balls);
    return bList;
  }

  public robotRenShu(playUsers: PlayUser[]) { return false; }

  private resetBallOrderPosition(orderNums: number[]) {
    const ballsNode = this.billiamNode.getChildByName('Balls');
    // 8球/9球
    ballsNode.active = true;
    const balls = ballsNode.children;
    var index = 0;
    for (const ball of balls) {
      const idx = orderNums[index];
      const pt = BallAttribute.eightBallPoints.get(`BallSphere${idx}`);
      EventManager.Instance().Emit('InitBallPosition', {
        ballName: ball.name, pos: new Vec3(pt.x, pt.y, pt.z),
      });
      index += 1;
    }
  }

  private changeUserHitBallColor(side: number) {
    const playUser = Game.Instance().playUsers[side];
    const color = playUser.color;
    if (!color.isBlackBallEight()) {
      const balls = this.getActiveBalls();
      var hasSameColor = false;
      for (const b of balls) {
        const ba = BallAttribute.getBallByName(b.name);
        if (color.isSameColor(ba.color)) {
          hasSameColor = true;
        }
      }
      if (!hasSameColor) {
        Game.Instance().setUserSideBlackColor(side);
      }
    }
  }
}

